﻿/*+===================================================================
File:      ItemBlock.cpp

Summary:   Định nghĩa các phương thức của CItemBlock.
===================================================================+*/

#include "ItemBlock.h"
#include "BulletItem.h"
#include "Explosion.h"
#include "PlayState.h"


// Trạng thái của ItemBlock.
#define STATUS_CLOSE			0
#define STATUS_OPENING			1
#define STATUS_OPEN				2
#define STATUS_CLOSING			3
#define STATUS_CAN_OPEN			4
#define STATUS_CLOSE_FOREVER	5

// SpriteId theo trạng thái của ItemBlock.
int spriteItemBlockId[6] =
{
	ID_SPRITE_ITEM_BLOCK_CLOSE,
	ID_SPRITE_ITEM_BLOCK_CHANGING,
	ID_SPRITE_ITEM_BLOCK_OPEN,
	ID_SPRITE_ITEM_BLOCK_CHANGING,
	ID_SPRITE_ITEM_BLOCK_CLOSE,
	ID_SPRITE_ITEM_BLOCK_CLOSE,
};

CItemBlock::CItemBlock(CBill* bill, D3DXVECTOR2 pos, int id, int typeID, int itemType) 
	: CMoveableObject(pos, id, typeID)
{
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_M_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_B_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_F_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_S_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_L_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_R_ITEM);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_ITEM_BLOCK_CLOSE);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_ITEM_BLOCK_CHANGING);
	CResourcesManager::GetInstance()->GetSprite(ID_SPRITE_ITEM_BLOCK_OPEN);
	m_nStatus = STATUS_CAN_OPEN;
	m_pSprite = m_pResourceManager->GetSprite(spriteItemBlockId[m_nStatus]);
	m_nItemType = ID_M_ITEM + itemType;
	m_timeChange = 0.3f;
	m_bill = bill;

	m_pTextureBox = m_pResourceManager->GetTexture(ID_TEXTURE_GROUND_BOX);
}

CItemBlock::~CItemBlock()
{

}

void CItemBlock::Update(float timeFrame)
{	
	if (!m_bIsLive)
		return;

	m_pSprite->Update(timeFrame);

	D3DXVECTOR2 billPos = m_bill->GetPos();
	if (g_nCurentLvl == ID_LEVEL2)
	{
		// Khi bill đến khoảng cách nhất định -> mở ItemBlock ra.
		if (m_nStatus == STATUS_CAN_OPEN && m_pos.y - 80 < billPos.y)
		{
			m_nStatus = STATUS_CLOSE;
		}

		// Khi bill xa ra 1 khoảng cách nhất định -> đóng ItemBlock lại.
		if (m_nStatus != STATUS_CAN_OPEN && m_nStatus != STATUS_CLOSE_FOREVER && billPos.y > m_pos.y + 220)
		{
			m_nStatus = STATUS_CLOSE_FOREVER;
		}
	}
	else
	{
		// Khi bill đến khoảng cách nhất định -> mở ItemBlock ra.
		if (m_nStatus == STATUS_CAN_OPEN && m_pos.x - 250 < billPos.x)
		{
			m_nStatus = STATUS_CLOSE;
		}

		// Khi bill xa ra 1 khoảng cách nhất định -> đóng ItemBlock lại.
		if (m_nStatus != STATUS_CAN_OPEN && m_nStatus != STATUS_CLOSE_FOREVER  && billPos.x > m_pos.x + 250)
		{
			m_nStatus = STATUS_CLOSE_FOREVER;
		}
	}

	if (m_nStatus != STATUS_CLOSE_FOREVER && m_nStatus != STATUS_CAN_OPEN)
	{
		if (m_timeChange > 0)
		{
			m_timeChange -= timeFrame;
		}
		else
		{
			m_nStatus = (m_nStatus + 1) % 4;
			if (m_nStatus == STATUS_OPEN || m_nStatus == STATUS_CLOSE)
				m_timeChange = 1.0f;
			else
				m_timeChange = 0.15f;
		}
	}

	m_pSprite = m_pResourceManager->GetSprite(spriteItemBlockId[m_nStatus]);
}

void CItemBlock::UpdateCollision(vector<CGameObject*> vecGameObjs, float timeFrame)
{
	if (!m_bIsLive)
		return;

	float timeCollision = timeFrame;
	CGameObject* objCollision = NULL; // Đối tượng va chạm sớm nhất.
	float normalx = 0.0f, normaly = 0.0f;

	// Xử lí va chạm giữ CItemBlock với đạn của Bill
	for (int i = 0; i < CPlayState::s_billBullets.size(); i++)
	{
		if (CPlayState::s_billBullets[i]->IsLive())
		{
			float t = CheckCollision(CPlayState::s_billBullets[i], normalx, normaly, timeFrame);

			if (t < timeFrame && t < timeCollision)
			{
				// Tìm đối tượng và thời gian va chạm sớm nhất.
				timeCollision = t;
				objCollision = CPlayState::s_billBullets[i];
			}
		}
	}

	// Update vị trí.
	m_v += m_a * timeCollision;
	m_pos += m_v * timeCollision;

	// Xử lí va chạm
	if (objCollision != NULL)
	{
		this->Kill();
		objCollision->Kill();
	}
}

bool CItemBlock::Kill()
{
	if (m_nStatus != STATUS_CLOSE && m_nStatus != STATUS_CLOSE_FOREVER && m_nStatus != STATUS_CAN_OPEN)
	{
		m_bIsLive = false;

		CBulletItem* bulletItem = new CBulletItem(m_pos, 0, m_nItemType);
		CExplosion* explosion = new CExplosion(m_pos, 0, ID_SMALL_EXPLOSION);

		CPlayState::s_objsOutSideQuadTree.push_back(bulletItem);
		CPlayState::s_objsOutSideQuadTree.push_back(explosion);

		return true;
	}

	return false;
}